package com.ruoyi.personnel.wechat.utils;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLDecoder;
import java.security.Security;
import java.util.Base64;
import java.io.UnsupportedEncodingException;

public class AESDecryption {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    /*
     * 解密微信小程序用户信息
     * @param encryptedData 包括敏感数据在内的完整用户信息的加密数据
     * @param sessionKey 会话密钥
     * @param iv 加密算法的初始向量
     * @return 解密后的用户信息
     */
    public static String decrypt(String encryptedData, String sessionKey, String iv) {
        try {
            // 从接口获取的 encryptedData、iv 和 session_key

            // 如果 encryptedData 可能包含 URL 编码的字符，先替换 URL 编码的 +
            encryptedData = encryptedData.replace("+", "%2B");

            // 使用 URLDecoder 解码，如果确实存在 URL 编码
            encryptedData = URLDecoder.decode(encryptedData, "UTF-8");

            // Base64 解码
            byte[] keyBytes = Base64.getDecoder().decode(sessionKey);
            byte[] ivBytes = Base64.getDecoder().decode(iv);
            byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);

            // 创建解密秘钥和初始向量
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);

            // 创建 Cipher 对象并设置解密模式
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

            // 解密数据
            byte[] originalBytes = cipher.doFinal(encryptedBytes);

            // 将解密的字节数组转换为字符串
            String originalData = new String(originalBytes, "UTF-8");

            // 输出原始数据
//            System.out.println("解密后的数据: " + originalData);
            return originalData;
        } catch (UnsupportedEncodingException e) {
            System.err.println("URL 解码失败: " + e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}